<template>
  <div class="role-management">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>角色管理</span>
          <div class="header-actions">
            <el-button type="primary" @click="handleAdd">
              <el-icon><Plus /></el-icon>
              新增角色
            </el-button>
            <el-button type="success" :disabled="selectedRoles.length === 0" @click="handleBatchExport">
              <el-icon><Download /></el-icon>
              导出选中
            </el-button>
            <el-button type="warning" :disabled="selectedRoles.length === 0" @click="handleBatchPermission">
              <el-icon><Key /></el-icon>
              批量授权
            </el-button>
          </div>
        </div>
      </template>

      <!-- 搜索表单 -->
      <el-form :inline="true" :model="searchForm" class="search-form">
        <el-form-item label="角色名称">
          <el-input v-model="searchForm.roleName" placeholder="请输入角色名称" clearable @keyup.enter="handleSearch" />
        </el-form-item>
        <el-form-item label="角色编码">
          <el-input v-model="searchForm.roleCode" placeholder="请输入角色编码" clearable @keyup.enter="handleSearch" />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="请选择状态" clearable @change="handleSearch">
            <el-option label="全部" value="" />
            <el-option label="启用" :value="1" />
            <el-option label="禁用" :value="0" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">
            <el-icon><Search /></el-icon>
            搜索
          </el-button>
          <el-button @click="handleReset">
            <el-icon><Refresh /></el-icon>
            重置
          </el-button>
        </el-form-item>
      </el-form>

      <!-- 批量操作工具栏 -->
      <div class="batch-toolbar" v-if="selectedRoles.length > 0">
        <span>已选择 {{ selectedRoles.length }} 项</span>
        <el-button type="danger" size="small" @click="handleBatchDelete">
          <el-icon><Delete /></el-icon>
          批量删除
        </el-button>
        <el-button type="warning" size="small" @click="handleBatchDisable">
          <el-icon><CircleClose /></el-icon>
          批量禁用
        </el-button>
        <el-button type="success" size="small" @click="handleBatchEnable">
          <el-icon><CircleCheck /></el-icon>
          批量启用
        </el-button>
      </div>

      <el-table 
        :data="roleList" 
        style="width: 100%" 
        v-loading="loading"
        @selection-change="handleSelectionChange"
        row-key="id"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column prop="roleName" label="角色名称" width="120" />
        <el-table-column prop="roleCode" label="角色编码" width="120" />
        <el-table-column prop="description" label="角色描述" min-width="200" show-overflow-tooltip />
        <el-table-column prop="sort" label="排序" width="80" />
        <el-table-column prop="userCount" label="用户数" width="80">
          <template #default="{ row }">
            <el-tag type="info">{{ row.userCount || 0 }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="80">
          <template #default="{ row }">
            <el-tag :type="row.status === 1 ? 'success' : 'danger'">
              {{ row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="160" />
        <el-table-column label="操作" width="300" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
            <el-button 
              :type="row.status === 1 ? 'danger' : 'success'" 
              link 
              @click="handleToggleStatus(row)"
            >
              {{ row.status === 1 ? '禁用' : '启用' }}
            </el-button>
            <el-button type="warning" link @click="handlePermission(row)">权限分配</el-button>
            <el-button type="danger" link @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-pagination
        v-model:current-page="pageInfo.pageNum"
        v-model:page-size="pageInfo.pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-card>

    <!-- 新增/编辑角色对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="500px"
      @close="handleDialogClose"
    >
      <el-form
        ref="roleFormRef"
        :model="roleForm"
        :rules="roleRules"
        label-width="80px"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="roleForm.roleName" placeholder="请输入角色名称" maxlength="30" show-word-limit :disabled="!!roleForm.id" />
        </el-form-item>
        <el-form-item label="角色编码" prop="roleCode">
          <el-input v-model="roleForm.roleCode" placeholder="请输入角色编码" :disabled="!!roleForm.id" maxlength="50" show-word-limit />
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input 
            v-model="roleForm.description" 
            type="textarea" 
            :rows="3"
            placeholder="请输入角色描述" 
          />
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="roleForm.sort" :min="0" :max="999" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-switch
            v-model="roleForm.status"
            :active-value="0"
            :inactive-value="1"
            active-text="启用"
            inactive-text="禁用"
            active-color="#13ce66"
            inactive-color="#ff4949"
          />
          <span class="status-tips" :class="roleForm.status === 0 ? 'status-enable' : 'status-disable'">
            {{ roleForm.status === 0 ? '角色可正常分配' : '角色无法分配' }}
          </span>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="submitLoading" @click="handleSubmit">
          确定
        </el-button>
      </template>
    </el-dialog>

    <!-- 权限分配对话框 -->
    <el-dialog
      v-model="permissionDialogVisible"
      title="权限分配"
      width="600px"
      @close="handlePermissionDialogClose"
    >
      <div class="permission-header">
        <el-alert
          title="提示：勾选菜单表示该角色拥有此菜单的访问权限"
          type="info"
          :closable="false"
        />
      </div>
      <el-tree
        ref="menuTreeRef"
        :data="menuTree"
        show-checkbox
        node-key="id"
        :props="treeProps"
        :default-checked-keys="checkedMenuIds"
        @check-change="handleMenuCheckChange"
        default-expand-all
        check-strictly
      />
      <template #footer>
        <el-button @click="permissionDialogVisible = false">取消</el-button>
        <el-button @click="handleCheckAll">全选</el-button>
        <el-button @click="handleUncheckAll">全不选</el-button>
        <el-button type="primary" :loading="permissionLoading" @click="handleSavePermission">
          保存
        </el-button>
      </template>
    </el-dialog>

    <!-- 批量授权对话框 -->
    <el-dialog
      v-model="batchPermissionDialogVisible"
      title="批量授权"
      width="600px"
      @close="handleBatchPermissionDialogClose"
    >
      <div class="batch-permission-content">
        <el-alert
          title="提示：将为选中的角色统一分配以下权限"
          type="info"
          :closable="false"
          style="margin-bottom: 20px;"
        />
        <el-tree
          ref="batchMenuTreeRef"
          :data="menuTree"
          show-checkbox
          node-key="id"
          :props="treeProps"
          default-expand-all
          check-strictly
        />
      </div>
      <template #footer>
        <el-button @click="batchPermissionDialogVisible = false">取消</el-button>
        <el-button @click="handleBatchCheckAll">全选</el-button>
        <el-button @click="handleBatchUncheckAll">全不选</el-button>
        <el-button type="primary" :loading="batchPermissionLoading" @click="handleSaveBatchPermission">
          保存
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
import { Search, Refresh, Plus } from '@element-plus/icons-vue'
import {
  getRolePage,
  createRole,
  updateRole,
  deleteRole,
  updateRoleStatus,
  getRolePermissions,
  assignRolePermissions
} from '@/api/system'
import { getMenuList } from '@/api/system'
import type { Role, Permission, Menu } from '@/types/api'
import * as XLSX from 'xlsx'

const loading = ref(false)
const roleList = ref<Role[]>([])
const total = ref(0)

const searchForm = reactive({
  roleName: '',
  roleCode: '',
  status: undefined as number | undefined
})

const pageInfo = reactive({
  pageNum: 1,
  pageSize: 10
})

const dialogVisible = ref(false)
const submitLoading = ref(false)
const permissionLoading = ref(false)
const batchPermissionLoading = ref(false)
const roleFormRef = ref<FormInstance>()

const roleForm = reactive({
  id: undefined as number | undefined,
  roleName: '',
  roleCode: '',
  description: '',
  sort: 0,
  status: 1
})

const roleRules: FormRules = {
  roleName: [
    { required: true, message: '请输入角色名称', trigger: 'blur' },
    { min: 2, max: 30, message: '角色名称长度应在2-30个字符之间', trigger: 'blur' }
  ],
  roleCode: [
    { required: true, message: '请输入角色编码', trigger: 'blur' },
    { min: 3, max: 50, message: '角色编码长度应在3-50个字符之间', trigger: 'blur' },
    { pattern: /^[A-Z_]+$/, message: '角色编码只能包含大写字母和下划线', trigger: 'blur' }
  ],
  status: [{ required: true, message: '请选择状态', trigger: 'change' }]
}

const permissionDialogVisible = ref(false)
const batchPermissionDialogVisible = ref(false)
const permissionLoading = ref(false)
const menuTreeRef = ref()
const batchMenuTreeRef = ref()
const menuTree = ref<Menu[]>([])
const checkedMenuIds = ref<number[]>([])
const currentRoleId = ref<number | undefined>(undefined)
const selectedRoles = ref<Role[]>([])

const treeProps = {
  children: 'children',
  label: 'menuName'
}

const dialogTitle = computed(() => 
  roleForm.id ? '编辑角色' : '新增角色'
)

const fetchRoleList = async () => {
  loading.value = true
  try {
    const params = {
      ...pageInfo,
      ...searchForm
    }
    // 移除空值参数
    Object.keys(params).forEach(key => {
      if (params[key] === '' || params[key] === null || params[key] === undefined) {
        delete params[key]
      }
    })
    const response = await getRolePage(params)
    roleList.value = response.records
    total.value = response.total
  } catch (error) {
    ElMessage.error('获取角色列表失败')
  } finally {
    loading.value = false
  }
}

const fetchMenuTree = async () => {
  try {
    const response = await getMenuList()
    menuTree.value = buildMenuTree(response)
  } catch (error) {
    ElMessage.error('获取菜单列表失败')
  }
}

const buildMenuTree = (menus: Menu[]): Menu[] => {
  const menuMap = new Map<number, Menu>()
  const result: Menu[] = []

  // 先构建映射
  menus.forEach(menu => {
    menuMap.set(menu.id, { ...menu, children: [] })
  })

  // 构建树形结构
  menus.forEach(menu => {
    if (menu.parentId === 0) {
      result.push(menuMap.get(menu.id)!)
    } else {
      const parent = menuMap.get(menu.parentId)
      if (parent) {
        parent.children!.push(menuMap.get(menu.id)!)
      }
    }
  })

  return result
}
// 搜索
const handleSearch = () => {
  pageInfo.pageNum = 1
  fetchRoleList()
}

// 重置搜索
const handleReset = () => {
  searchForm.roleName = ''
  searchForm.roleCode = ''
  searchForm.status = undefined
  handleSearch()
}

const handleAdd = () => {
  roleForm.id = undefined
  roleForm.roleName = ''
  roleForm.roleCode = ''
  roleForm.description = ''
  roleForm.sort = 0
  roleForm.status = 1
  dialogVisible.value = true
}

const handleEdit = (row: Role) => {
  roleForm.id = row.id
  roleForm.roleName = row.roleName
  roleForm.roleCode = row.roleCode
  roleForm.description = row.description
  roleForm.sort = row.sort
  roleForm.status = row.status
  dialogVisible.value = true
}

const handleToggleStatus = async (row: Role) => {
  try {
    await ElMessageBox.confirm(
      `确定要${row.status === 1 ? '禁用' : '启用'}角色"${row.roleName}"吗？`,
      '提示',
      { type: 'warning' }
    )
    
    await updateRoleStatus(row.id, row.status === 1 ? 0 : 1)
    ElMessage.success(`${row.status === 1 ? '禁用' : '启用'}成功`)
    fetchRoleList()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('操作失败')
    }
  }
}

const handleDelete = async (row: Role) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除角色"${row.roleName}"吗？`,
      '提示',
      { type: 'warning' }
    )
    
    await deleteRole(row.id)
    ElMessage.success('删除成功')
    fetchRoleList()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

const handlePermission = async (row: Role) => {
  currentRoleId.value = row.id
  permissionDialogVisible.value = true
  
  try {
    // 获取角色的菜单权限
    const rolePermissions = await getRolePermissions(row.id)
    checkedMenuIds.value = rolePermissions.map((permission: Permission) => permission.id)
    
    // 同时获取菜单列表用于树形展示
    const menuResponse = await getMenuList()
    menuTree.value = buildMenuTree(menuResponse.map((menu: Menu) => ({ ...menu, children: menu.children || [] })))
  } catch (error) {
    ElMessage.error('获取角色权限失败')
    checkedMenuIds.value = []
  }
}

const handleMenuCheckChange = () => {
  // 树形选择变化时的处理
}

const handleSavePermission = async () => {
  if (!currentRoleId.value) return
  
  permissionLoading.value = true
  try {
    const checkedNodes = menuTreeRef.value.getCheckedNodes()
    const permissionIds = checkedNodes.map((node: any) => node.id)
    
    await assignRolePermissions(currentRoleId.value, permissionIds)
    ElMessage.success('权限分配成功')
    permissionDialogVisible.value = false
  } catch (error) {
    ElMessage.error('权限分配失败')
  } finally {
    permissionLoading.value = false
  }
}

const handleSubmit = async () => {
  if (!roleFormRef.value) return
  
  try {
    await roleFormRef.value.validate()
    submitLoading.value = true
    
    if (roleForm.id) {
      await updateRole(roleForm.id, roleForm)
      ElMessage.success('更新成功')
    } else {
      await createRole(roleForm)
      ElMessage.success('创建成功')
    }
    
    dialogVisible.value = false
    fetchRoleList()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('操作失败')
    }
  } finally {
    submitLoading.value = false
  }
}

const handleDialogClose = () => {
  roleFormRef.value?.resetFields()
}

const handlePermissionDialogClose = () => {
  checkedMenuIds.value = []
  currentRoleId.value = undefined
}

// 全选/全不选
const handleCheckAll = () => {
  const allMenuIds = getAllMenuIds(menuTree.value)
  menuTreeRef.value?.setCheckedKeys(allMenuIds)
}

const handleUncheckAll = () => {
  menuTreeRef.value?.setCheckedKeys([])
}

const handleSizeChange = (val: number) => {
  pageInfo.pageSize = val
  fetchRoleList()
}

const handleCurrentChange = (val: number) => {
  pageInfo.pageNum = val
  fetchRoleList()
}

onMounted(() => {
  fetchRoleList()
})
</script>

<style scoped>
.role-management {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.search-form {
  margin-bottom: 20px;
  padding: 20px;
  background: #f5f7fa;
  border-radius: 4px;
}

.batch-toolbar {
  margin-bottom: 15px;
  padding: 10px 15px;
  background: #e6f7ff;
  border: 1px solid #91d5ff;
  border-radius: 4px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.batch-toolbar span {
  margin-right: auto;
  font-weight: 500;
  color: #1890ff;
}

.upload-demo {
  display: inline-block;
}

.menu-tree {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 10px;
  max-height: 400px;
  overflow-y: auto;
}

.tree-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #e4e7ed;
}

.tree-actions {
  display: flex;
  gap: 10px;
}

.status-tips {
  margin-left: 10px;
  font-size: 12px;
  color: #909399;
}

.status-enable {
  color: #67c23a;
}

.status-disable {
  color: #f56c6c;
}

.permission-header {
  margin-bottom: 20px;
}

.batch-permission-content {
  padding: 10px 0;
}

.el-pagination {
  margin-top: 20px;
  justify-content: flex-end;
}

@media (max-width: 768px) {
  .header-actions {
    flex-wrap: wrap;
  }
  
  .search-form {
    display: flex;
    flex-direction: column;
  }
  
  .batch-toolbar {
    flex-wrap: wrap;
    gap: 8px;
  }
  
  .batch-toolbar span {
    width: 100%;
    margin-bottom: 8px;
  }
  
  .tree-actions {
    flex-wrap: wrap;
    gap: 5px;
  }
}